package org.copper.ui
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.Sprite;

	public class VPannel extends CSprite
	{
		public static const TO_LEFT:uint = 0;
		public static const TO_CENTER:uint = 1;
		public static const TO_RIGHT:uint = 2;
		
		
		private var m_background:Bitmap = null;
		
		private var m_step:Number = 10;
		private var m_topBorder:Number = 5;
		private var m_buttomBorder:Number = 5;
		private var m_centerOffset:Number = 0;
		
		private var m_horizontalAlign:uint = TO_CENTER;
		
		private var m_top:Vector.<DisplayObject>;
		private var m_center:Vector.<DisplayObject>;
		private var m_buttom:Vector.<DisplayObject>;
		
		private var m_layout:Sprite;
		private var m_foreground:Sprite;
		
		
		
		//override of width and height to set those properties regardless to sprite properties.
		private var m_forcedWidth:Number = 0;
		private var m_forcedHeight:Number = 0;
		
		public function VPannel(Background:BitmapData = null)
		{
			super();
			
			if (Background != null)
			{
				m_background = new Bitmap(Background);
				super.addChild(m_background);
				m_forcedWidth = Background.width;
				m_forcedHeight = Background.height;
			}
			
			
			m_layout = new Sprite();
			m_foreground = new Sprite();
			m_top = new Vector.<DisplayObject>();
			m_center = new Vector.<DisplayObject>();
			m_buttom = new Vector.<DisplayObject>();
			
			super.addChild(m_layout);
			super.addChild(m_foreground);
		}
		
		
		public function removeFromCenter(child:DisplayObject, updateOnRemove:Boolean = true):Boolean
		{
			const index:int = m_center.indexOf(child);
			if (m_layout.contains(child) && index >= 0)
			{
				m_layout.removeChild(child);
				m_center.splice(index, 1);
				if (updateOnRemove) updateLayout();
				
				return true;
			}
			return false;
		}
		
		public function removeFromButtom(child:DisplayObject, updateOnRemove:Boolean = true):Boolean
		{
			const index:int = m_buttom.indexOf(child);
			if (m_layout.contains(child) && index >= 0)
			{
				m_layout.removeChild(child);
				m_buttom.splice(index, 1);
				if (updateOnRemove) updateLayout();
				
				return true;
			}
			return false;
		}
		
		public function removeFromTop(child:DisplayObject, updateOnRemove:Boolean = true):Boolean
		{
			const index:int = m_top.indexOf(child);
			if (m_layout.contains(child) && index >= 0)
			{
				m_layout.removeChild(child);
				m_top.splice(index, 1);
				if (updateOnRemove) updateLayout();
				
				return true;
			}
			return false;
		}
		
		
		public function addToCenter(child:DisplayObject, updateOnAdd:Boolean = true):DisplayObject
		{
			const result:DisplayObject = m_layout.addChild(child);
			m_center.push(child);
			if (updateOnAdd) updateLayout();
			return result;
		}
		
		public function addToButtom(child:DisplayObject, updateOnAdd:Boolean = true):DisplayObject
		{
			const result:DisplayObject = m_layout.addChild(child);
			m_buttom.push(child);
			if (updateOnAdd) updateLayout();
			return result;
		}
		
		public function addToTop(child:DisplayObject, updateOnAdd:Boolean = true):DisplayObject
		{
			const result:DisplayObject = m_layout.addChild(child);
			m_top.push(child);
			if (updateOnAdd) updateLayout();
			return result;
		}
		
		public function updateLayout():void
		{
			updateTop();
			updateCenter();
			updateButtom();
		}
		
		//====================arangments=======================
		private function updateTop():void
		{
			const len:uint = m_top.length;
			if (len > 0)
			{
				var currentY:Number = m_topBorder;
				for(var i:uint = 0; i < len; i++)
				{
					const obj:DisplayObject = m_top[i];
					if (obj.visible)
					{
						switch(m_horizontalAlign)
						{
							case TO_CENTER:
								obj.x = (this.width - obj.width) * 0.5;
								break;
							case TO_RIGHT:
								obj.x = this.width - obj.width;
								break;
							case TO_LEFT:
								obj.x = 0;
								break;
						}
						
						obj.y = currentY;
						currentY += obj.height + m_step;
					}
				}
			}
		}
		
		
		private function updateButtom():void
		{
			const len:uint = m_buttom.length;
			if (len > 0)
			{
				var currentY:Number = this.height - m_buttomBorder;
				for(var i:uint = 0; i < len; i++)
				{
					const obj:DisplayObject = m_buttom[i];
					if (obj.visible)
					{
						switch(m_horizontalAlign)
						{
							case TO_CENTER:
								obj.x = (this.width - obj.width) * 0.5;
								break;
							case TO_RIGHT:
								obj.x = this.width - obj.width;
								break;
							case TO_LEFT:
								obj.x = 0;
								break;
						}
						
						obj.y = currentY - obj.height;
						currentY -= (obj.height + m_step);
					}
				}
			}
		}
		
		
		private function updateCenter():void
		{
			const len:uint = m_center.length;
			if (len > 0)
			{
				var i:uint = 0;
				var center:Number = m_centerOffset + (this.height * 0.5);
				var heightOfComponents:Number = 0;
				var obj:DisplayObject;
				
				for(;i < len; i++)
				{
					obj = m_center[i];
					if (obj.visible)
					{
						heightOfComponents += obj.height + m_step;
					}
				}
				
				var currentY:Number = center - (heightOfComponents * 0.5);
				for(i = 0; i < len; i++)
				{
					obj = m_center[i];
					if (obj.visible)
					{
						switch(m_horizontalAlign)
						{
							case TO_CENTER:
								obj.x = (this.width - obj.width) * 0.5;
								break;
							case TO_RIGHT:
								obj.x = this.width - obj.width;
								break;
							case TO_LEFT:
								obj.x = 0;
								break;
						}
						
						obj.y = currentY;
						currentY += obj.height + m_step;
					}
				}
			}
		}
		
		//EOF====================arangments=======================
		
		
		override public function get height():Number
		{
			return m_forcedHeight;
		}
		
		override public function set height(value:Number):void
		{
			if (m_background != null)
				return;
			
			m_forcedHeight = value;
		}
		
		override public function get width():Number
		{
			return m_forcedWidth;
		}
		
		override public function set width(value:Number):void
		{
			if (m_background != null)
				return;
			
			m_forcedWidth = value;
		}
		
		override public function addChild(child:DisplayObject):DisplayObject
		{
			return m_foreground.addChild(child);
		}
		
		override public function addChildAt(child:DisplayObject, index:int):DisplayObject
		{
			return m_foreground.addChildAt(child, index);
		}
		
		override public function contains(child:DisplayObject):Boolean
		{
			return m_foreground.contains(child);
		}
		
		override public function getChildAt(index:int):DisplayObject
		{
			return m_foreground.getChildAt(index);
		}
		
		override public function getChildByName(name:String):DisplayObject
		{
			return m_foreground.getChildByName(name);
		}
		
		override public function getChildIndex(child:DisplayObject):int
		{
			return m_foreground.getChildIndex(child);
		}
		
		public function get step():Number
		{
			return m_step;
		}
		
		public function set step(value:Number):void
		{
			m_step = value;
			updateLayout();
		}
		
		public function set topBorder(value:Number):void
		{
			m_topBorder = value;
			updateLayout();
		}
		
		public function get topBorder():Number
		{
			return m_topBorder;
		}
		
		public function set buttomBorder(value:Number):void
		{
			m_buttomBorder = value;
			updateLayout();
		}
		
		public function get buttomBorder():Number
		{
			return m_buttomBorder;
		}
		
		public function get centerOffset():Number
		{
			return m_centerOffset;
		}
		
		public function set centerOffset(value:Number):void
		{
			m_centerOffset = value;
			updateLayout();
		}
		
		public function get horizontalAlign():uint
		{
			return m_horizontalAlign;
		}
		
		public function set horizontalAlign(value:uint):void
		{
			m_horizontalAlign = value > TO_RIGHT?TO_CENTER:value;
			updateLayout();
		}
	}
}